import java.awt.Graphics;

import me.w70.bot.Bot;
import me.w70.bot.scripting.Random;
import me.w70.bot.wrappers.RSInterface;
import me.w70.bot.wrappers.RSInterfaces;
import me.w70.bot.wrappers.RSNPC;
import me.w70.bot.wrappers.RSObject;
import me.w70.hooks.Tile;


public class EvilTwin extends Random {


	private enum State {
		AtMolly, CatchTwin, Done, Finalize;
	}

	boolean caught = false;
	RSObject claw;

	int clawID = 14976;
	int closeButton = 33;
	int controlID = 14978;

	int controlsIface = 240;
	RSObject door;
	int doorID = 14982;

	RSNPC molly;
	int mollyID;

	
	int submitButton = 23;
	boolean talked = false;

	int twinID;

	public EvilTwin() {
	}

	@Override
	public boolean canRun() {
		if (!isLoggedIn()) {
			return false;
		}

		claw = claw();
		if (claw != null) {
			// Bot.addMessage(this, " Claw Found ");
			molly = molly();
			if (molly != null) {
				// Bot.addMessage(this, " Molly Found ");
				mollyID = molly.getID();
				twinID = mollyID - 40; // Thankz to Illusion
				Bot.addMessage(this, "Molly ID: " + mollyID);
				Bot.addMessage(this, "Expected Twin ID: " + twinID);
				return true;
			}
		}
		return false;
	}

	private RSObject claw() {
		return findObject(50, clawID);
	}

	private boolean clawOn(final Tile location) {

		return claw.getLocation().equals(location);

	}

	private State getMollyState() {
		if ((molly = molly()) == null && (claw = claw()) == null) {
			return State.Done;
		}

		if (caught) {
			return State.Finalize;
		}

		if (withMolly()) {
			return State.AtMolly;
		}

		return State.CatchTwin;
	}
	
	int attempts = 0;

	@Override
	public int loop() {
		if (canContinue()) {
			clickContinue();
			return random(800, 1000);
		}
		if (getMyPlayer().isMoving()) {
			return random(800, 1000);
		}
		switch (getMollyState()) {
		case AtMolly:
			final RSInterface talkIface = RSInterfaces.getInterface(228, 3);
			if (talkIface.isValid()) {
				atInterface(talkIface);
				break;
			}
			door = findObject(doorID);
			if (door != null) {
				atDoor(door, "east", "Open Door");
			}
			break;

		case CatchTwin:
			if(attempts > 2) {
				caught = true;
				break;
			}
			final RSInterface cIface = RSInterfaces.getInterface(controlsIface,0);
			if (cIface.isValid()) {
				final RSNPC twin = getNearestNPCByID(twinID);
				if (!clawOn(twin.getLocation())) {
					moveCLayTo(twin.getLocation());
					break;
				}
				atInterface(cIface.getChild(submitButton));
				attempts++;
				break;
			}

			final RSObject controller = findObject(50, controlID);
			if (controller != null) {
				atObject(controller, "Use");
			}
			break;

		case Done:
			return -1;

		case Finalize:
			if (distanceTo(molly) > 5) {
				door = findObject(doorID);
				atDoor(door, "east", "Open Door");
				break;
			}
			break;
		}
		return random(400, 800);
	}

	private RSNPC molly() {
		return getNearestNPCByName("Molly");
	}

	private void moveCLayTo(final Tile tLoc) {

		final Tile cLoc = claw.getLocation();
		final RSInterface cIface = RSInterfaces.getInterface(controlsIface,0);

		final int tLocX = tLoc.getX();
		final int tLocY = tLoc.getY();

		final int cLocX = cLoc.getX();
		final int cLocY = cLoc.getY();

		if (tLocX < cLocX) {
			// If Twin.X < Claw.X: move to Left
			atInterface(cIface.getChild(16));
			return;
		}

		if (tLocX > cLocX) {
			// If Twin.X > Claw.X: move to right
			atInterface(cIface.getChild(21));
			return;
		}

		if (tLocY < cLocY) {
			// If Twin.Y < Claw.Y: move up
			atInterface(cIface.getChild(6));
			return;
		}

		if (tLocX > cLocX) {
			// If Twin.Y > Claw.Y: move down
			atInterface(cIface.getChild(11));
			return;
		}

	}

	private boolean withMolly() {
		final Tile mTile = molly.getLocation();

		final int minX = mTile.getX() - 2;
		final int maxX = mTile.getX() + 5;

		final int minY = mTile.getY() - 2;
		final int maxY = mTile.getY() + 5;

		final int myX = getMyPlayer().getLocation().getX();
		final int myY = getMyPlayer().getLocation().getY();

		if (minX < myX && myX > maxX) {
			if (minY < myY && myY > maxY) {
				return true;
			}
		}

		return false;
	}

	@Override
	public void draw(Graphics g) {
		// TODO Auto-generated method stub
	}

	@Override
	public String getScriptAuthor() {
		// TODO Auto-generated method stub
		return "spooky";
	}

	@Override
	public String getScriptCategory() {
		// TODO Auto-generated method stub
		return "Random";
	}

	@Override
	public String getScriptDescription() {
		// TODO Auto-generated method stub
		return "Solves the Evil Twin Random";
	}

	@Override
	public String getScriptName() {
		// TODO Auto-generated method stub
		return "EvilTwin";
	}
}